package device

import (
	"errors"
	"fmt"

	"github.com/alecthomas/log4go"
	"pac/client"
	pb "pac/proto"
)

type ctlReq struct {
	reqPkt

	// 开启/接通
	on bool
}

type ctlRsp struct {
	rspPkt
}

func (p *ctlReq) String() string {
	return fmt.Sprintf("%s: ID: on=%v", p.CmdStr(), p.on)
}

func (p *ctlReq) parseParam() error {
	if len(p.Payload) == 0 {
		return errors.New("ctlReq.parseParam: invalid param")
	}

	if p.Payload[0] == 0 {
		p.on = false
	} else {
		p.on = true
	}

	return nil
}

func (p *ctlRsp) parseParam() error {
	return nil
}

func (p *ctlReq) adjustCmd() {
	if p != nil {
		p.Cmd = CmdCtlReq
	}
}

func (p *ctlRsp) adjustCmd() {
	if p != nil {
		p.Cmd = CmdCtlRsp
	}
}

func (p *ctlReq) marshalParams() ([]byte, error) {
	param, err := p.reqPkt.marshalParams()
	if err != nil {
		return param, err
	}
	if p.on {
		param = append(param, 1)
	} else {
		param = append(param, 0)
	}
	return param, nil
}

func (p *ctlRsp) marshalParams() ([]byte, error) {
	return p.rspPkt.marshalParams()
}

// Marshal 编码
func (p *ctlReq) Marshal() ([]byte, error) {
	return Marshal(p)
}

// Marshal 编码
func (p *ctlRsp) Marshal() ([]byte, error) {
	return Marshal(p)
}

// Process 处理
func (p *ctlReq) Process(cli *Client) error {
	return nil
}

// Process 处理
func (p *ctlRsp) Process(cli *Client) error {
	return nil
}

func CtrlOnOff(deviceID string, on bool) (errCode pb.ErrCode) {
	req := &ctlReq{
		on: on,
	}

	if len(deviceID) != 0 {
		cliSlice := client.FindClient(deviceID)
		if cliSlice == nil {
			log4go.Info("device %v offline", deviceID)
			return pb.ErrCode_OFFLINE
		}

		errCode = pb.ErrCode_FAILURE
		for _, cli := range cliSlice {
			err := cli.SendPacket(req)
			if err != nil {
				log4go.Warn("SendPacket failure: %v", err)
			} else {
				errCode = pb.ErrCode_SUCCESS
			}
		}

		return
	}

	cliSlice := client.GetAllClient(client.Device)
	if len(cliSlice) == 0 {
		return pb.ErrCode_OFFLINE
	}
	errCode = pb.ErrCode_FAILURE
	for _, cli := range cliSlice {
		err := cli.SendPacket(req)
		if err != nil {
			log4go.Warn("SendPacket failure: %v", err)
		} else {
			errCode = pb.ErrCode_SUCCESS
		}
	}
	return
}
